﻿using System;

using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Silvermoon.Shapes;

using Silvermoon.Controls.Base;
using Silvermoon.Utils;
using Silvermoon.OpenGL;
using Silvermoon.Controls.Interfaces;
using Silvermoon.Images;
using Silvermoon.Interfaces;

using Silvermoon.Windows;
using Silvermoon.UI;

namespace Silvermoon.Controls
{
    /// <summary>
    /// Provides a standard button, optionally with toggle mode.
    /// </summary>
    public class ContentButton : ButtonBase, IColor
    {
        #region Fields

        private bool canFocus = true;
        private Margin padding;
        private FontSprite font;
        //private Alignment alignment = Alignment.Center;
        //private Alignment lineAlignment = Alignment.Center;

        private Shape content;

        #endregion
        #region manager

 
        #endregion
        #region ctor

        public ContentButton()
            : base()
        {
            Opacity = 255;
     //       TextColor = SysColors.ButtonTextColor;
        }

        protected override void Dispose(bool dispose)
        {
            if (content != null) content.Dispose();
            content = null;
            base.Dispose(dispose);
        }

        /// <summary>
        /// Initializes the <see cref="Button"/> class.
        /// </summary>
        static ContentButton()
        {
            VisualStateManager.RegisterClassManager(typeof(Button), ButtonStateManagers.ButtonManager);
        }

        #endregion
        #region Props

        public FontSprite Font
        {
            get { return font; }
            set
            {
                if (font != value)
                {
                    font = value;
                    Invalidate(InvalidationFlag.Appearance);
                }
            }
        }

        //public Alignment Alignment
        //{
        //    get { return alignment; }
        //    set
        //    {
        //        if (alignment != value)
        //        {
        //            alignment = value;
        //            Invalidate(InvalidationFlag.Appearance);
        //        }
        //    }
        //}

        //public Alignment LineAlignment
        //{
        //    get { return lineAlignment; }
        //    set
        //    {
        //        if (lineAlignment != value)
        //        {
        //            lineAlignment = value;
        //            Invalidate(InvalidationFlag.Appearance);
        //        }
        //    }
        //}


        /// <summary>
        /// Gets or sets the margin for the layout of the content.
        /// </summary>
        public Margin Padding
        {
            get { return padding ?? Margin.Centered; ; }
            set
            {
                if (!Padding.Equals(value))
                {
                    padding = value;
                    Invalidate(InvalidationFlag.Layout);
                }
            }
        }

        public override bool CanFocus
        {
            get
            {
                return canFocus && base.CanFocus;
            }
        }

        public bool IsFocusable
        {
            get { return canFocus; }
            set { canFocus = value; }
        }

        /// <summary>
        /// Gets or sets the Content for the button.
        /// This can be any derived <see cref="Shape"/>. Strings and Textures can directly assigned to this value due to implict operators, 
        /// e.g. Content="Button" instead of Content=new StringShape{Content=Button}.
        /// </summary>
        public Shape Content
        {
            get { return content; }
            set
            {
                if (content != value)
                {
                    if (content != null)
                    {
                        Shapes.Remove(content);
                        content.Dispose();
                    }
                    content = value;
                    if (content != null) Shapes.AddLast(content);
                    OnContentChanged();
                }
            }
        }

        #endregion
        #region Methods

        protected override Shape CreateDefaultBackground()
        {
            //return new AccentShape();
            return new ButtonShape();
        }

        protected virtual void OnContentChanged()
        {
            Invalidate(InvalidationFlag.Layout | InvalidationFlag.Text);
            if (ContentChanged != null) ContentChanged(this, EventArgs.Empty);
        }

        protected override void OnLayout()
        {
            if (content != null)
            {
                if (CheckFlag(InvalidationFlag.Appearance | InvalidationFlag.Text))
                {
                    if (font != null)
                    {
                        StringShape ss = content as StringShape;
                        if (ss != null)
                        {
                            ss.Font = font;
                        }
                    }
                }
                if (CheckFlag(InvalidationFlag.Size | InvalidationFlag.Layout))
                {
                    content.Bounds = Padding.Layout(content.Bounds, this.Size);
                }
            }
            base.OnLayout();
        }

        #endregion
        #region IContextMenu Members
        #endregion
        #region events

        /// <summary>
        /// Occcurs when the text changes;
        /// </summary>
        public event EventHandler ContentChanged;
        #endregion
    }

    public class Button : ContentButton
    {
        #region operators

        public static implicit operator Button(string title)
        {
            return new Button { Content = title };
        }

        public static implicit operator Button(float title)
        {
            return new Button { Content = title.ToString() };
        }

        public static implicit operator Button(int title)
        {
            return new Button { Content = title.ToString() };
        }

        #endregion

    }


}

